#include "Client.h"
#include "Slot.h"
#include "Card.h"
#include "Table.h"

#define VERBOSE 1
Client::Client(Table* _table){
  
  emptyActiveCard = new Card(hearts, active, 999);
  emptyDeckCard = new Card(hearts, deck, 999);
  emptyPillageCard = new Card(hearts, pillage, 999);
  emptySpoilsCard = new Card(hearts, spoils, 999);
  emptyHandCard = new Card(hearts, hand, 999);
  
  emptySlot.setX(0);
  emptySlot.setY(0);
  emptySlot.setCard(emptyActiveCard);
  table = _table;
  cardX=0;
  cardY=0;
  suit=0;
  number=0;
  //window being the box that we're playing in
  windowMaxX = 78;
  windowMaxY = 36;
  windowXOffset = 0;
  windowYOffset = 1;
  initializeDisplay();
}

void Client::initializeDisplay(){
  gameDisplay.setTable(table);//doesn't actually do much besides set the table pointer.
//Iterates through and sets all possible locations into the Slot objects

    p1CardSlots[0].setX(18);
    p1CardSlots[0].setY(27);
    p1CardSlots[0].setCard(emptyDeckCard);

  for(int i = 1; i < 8; i++){
    p1CardSlots[i].setX(18 + 6*i);
    p1CardSlots[i].setY(27);
    p1CardSlots[i].setCard(emptyHandCard);
  }
 
  p2CardSlots[0].setX(8);
  p2CardSlots[0].setY(12);
  p2CardSlots[0].setCard(emptyDeckCard);
 
  p2CardSlots[1].setX(8);
  p2CardSlots[1].setY(12 + 5);
  p2CardSlots[1].setCard(emptyHandCard);

  p3CardSlots[0].setX(32);
  p3CardSlots[0].setY(4);
  p3CardSlots[0].setCard(emptyDeckCard);

  p3CardSlots[1].setX(32 + 6);
  p3CardSlots[1].setY(4);
  p3CardSlots[1].setCard(emptyHandCard);
    
  p4CardSlots[0].setX(64);
  p4CardSlots[0].setY(12);
  p4CardSlots[0].setCard(emptyDeckCard);

  p4CardSlots[1].setX(64);
  p4CardSlots[1].setY(12 + 5);
  p4CardSlots[1].setCard(emptyHandCard);

//Change the coordinates of the cards here if necessary
  activeSlots[0].setX(36);
  activeSlots[0].setY(21);
  activeSlots[0].setCard(emptyActiveCard);
  activeSlots[1].setX(17);
  activeSlots[1].setY(15);
  activeSlots[1].setCard(emptyActiveCard);
  activeSlots[2].setX(36);
  activeSlots[2].setY(9);
  activeSlots[2].setCard(emptyActiveCard);
  activeSlots[3].setX(55);
  activeSlots[3].setY(15);
  activeSlots[3].setCard(emptyActiveCard);
  pillageSlot.setX(32);
  pillageSlot.setY(15);
  pillageSlot.setCard(emptyPillageCard);

  spoilsSlot.setX(40);
  spoilsSlot.setY(15);
  spoilsSlot.setCard(emptySpoilsCard);



cout<<"Table is initialized. Press a key to begin game"<<endl;
//cin.ignore();
}

void Client::updateSlotValues(Table* table){
//PLAYER ONE'S HAND
  int handSize = table->players.at(0).getHand()->size();
  for(int i = 0; i < handSize; i++){

    p1CardSlots[i+1].setCard(table->players.at(0).getHand()->at(i));//assigns the slot's card to thisCard
  } 
}

void Client::drawTable(Table* table){ 

  //Creates the box to cover previous table dT4Sk5Zf2BX9
  gameDisplay.drawBox(windowXOffset,windowYOffset, windowMaxX,windowMaxY,0);
  //gameDisplay.eraseBox(windowXOffset,windowYOffset, windowMaxX,windowMaxY);
//p1 Deck
  gameDisplay.displayCard(p1CardSlots[0].getX(),p1CardSlots[0].getY(), 1, 18,0, &(table->players.at(0)));
  //This loop gives the player1's hand
  int handSize = table->players.at(0).getHand()->size();

//WAR FLAG
   //gameDisplay.displayCard(0,0, 1, 19,0);


    gameDisplay.displayCard(p1CardSlots[1].getX(),p1CardSlots[1].getY(), p1CardSlots[1].getCard()->getSuit(),p1CardSlots[1].getCard()->getRank(),0);
    gameDisplay.displayCard(p1CardSlots[2].getX(),p1CardSlots[2].getY(), p1CardSlots[2].getCard()->getSuit(),p1CardSlots[2].getCard()->getRank(),0);
    gameDisplay.displayCard(p1CardSlots[3].getX(),p1CardSlots[3].getY(), p1CardSlots[3].getCard()->getSuit(),p1CardSlots[3].getCard()->getRank(),0);
    gameDisplay.displayCard(p1CardSlots[4].getX(),p1CardSlots[4].getY(), p1CardSlots[4].getCard()->getSuit(),p1CardSlots[4].getCard()->getRank(),0);
    gameDisplay.displayCard(p1CardSlots[5].getX(),p1CardSlots[5].getY(), p1CardSlots[5].getCard()->getSuit(),p1CardSlots[5].getCard()->getRank(),0);
    gameDisplay.displayCard(p1CardSlots[6].getX(),p1CardSlots[6].getY(), p1CardSlots[6].getCard()->getSuit(),p1CardSlots[6].getCard()->getRank(),0);
    gameDisplay.displayCard(p1CardSlots[7].getX(),p1CardSlots[7].getY(), p1CardSlots[7].getCard()->getSuit(),p1CardSlots[7].getCard()->getRank(),0);
  
  //player2's Deck and Hand
  gameDisplay.displayCard(p2CardSlots[0].getX(),p2CardSlots[0].getY(), 2,deck,0,&(table->players.at(1)));
  gameDisplay.displayCard(p2CardSlots[1].getX(),p2CardSlots[1].getY(), 2,hand,0,&(table->players.at(1)));
  //player3's Deck and Hand
  gameDisplay.displayCard(p3CardSlots[0].getX(),p3CardSlots[0].getY(), 3,18,0,&(table->players.at(2)));
  gameDisplay.displayCard(p3CardSlots[1].getX(),p3CardSlots[1].getY(), 3,14,0,&(table->players.at(2)));
  //player4's Deck and Hand
  gameDisplay.displayCard(p4CardSlots[0].getX(),p4CardSlots[0].getY(), 4,18,0,&(table->players.at(3)));
  gameDisplay.displayCard(p4CardSlots[1].getX(),p4CardSlots[1].getY(), 4,14,0,&(table->players.at(3)));
  //Active Cards 
gameDisplay.displayCard(activeSlots[0].getX(),activeSlots[0].getY(), table->getCardOf(0).getSuit(),table->getCardOf(0).getRank(),0);
gameDisplay.displayCard(activeSlots[1].getX(),activeSlots[1].getY(), table->getCardOf(1).getSuit(),table->getCardOf(1).getRank(),0);
gameDisplay.displayCard(activeSlots[2].getX(),activeSlots[2].getY(), table->getCardOf(2).getSuit(),table->getCardOf(2).getRank(),0);
gameDisplay.displayCard(activeSlots[3].getX(),activeSlots[3].getY(), table->getCardOf(3).getSuit(),table->getCardOf(3).getRank(),0);


  //Pillage and Spoils
  //needs to be set in the slots properly still:
  gameDisplay.displayCard(pillageSlot.getX(),pillageSlot.getY(),0,pillage,0);
  gameDisplay.displayCard(spoilsSlot.getX(),spoilsSlot.getY(),0,spoils,0);
  
	//USE THIS FOR DEBUGGING - for seeing what a card value isdT4Sk5Zf2BX9
/* 
    int tempRank = table->players.at(0).getHand()->at(2)->getRank(); //modify this and the one below
    int tempSuit = table->players.at(0).getHand()->at(2)->getSuit();
    cout<<tempRank<<endl;
    gameDisplay.displayCard(0,0, tempSuit, tempRank,0);
*/
//cout<<table->players.at(0).getHand()->size()<<endl;dT4Sk5Zf2BX9
}

Slot Client::checkHitBoxes(){
    for(int i=0; i<8; i++){
      if(between (p1CardSlots[i].getX(), clickX, p1CardSlots[i].getX()+5)){
	if(between(p1CardSlots[i].getY(), clickY, p1CardSlots[i].getY()+4)){
          return p1CardSlots[i];
        }
      }
    }
    for(int i=0; i<2; i++){
      if(between (p2CardSlots[i].getX(), clickX, p2CardSlots[i].getX()+5)){
	if(between(p2CardSlots[i].getY(), clickY, p2CardSlots[i].getY()+4)){
          return p2CardSlots[i];
        }
      }
    }
    for(int i=0; i<2; i++){
      if(between (p3CardSlots[i].getX(), clickX, p3CardSlots[i].getX()+5)){
	if(between(p3CardSlots[i].getY(), clickY, p3CardSlots[i].getY()+4)){
          return p3CardSlots[i];
        }
      }
    }
    for(int i=0; i<2; i++){
      if(between (p4CardSlots[i].getX(), clickX, p4CardSlots[i].getX()+5)){
	if(between(p4CardSlots[i].getY(), clickY, p4CardSlots[i].getY()+4)){
          return p4CardSlots[i];
        }
      }
    }
/* currently we dont need to click on pillage and spoils and active slots but we may later
    if(between(pillageSlot.getX(), clickX, pillageSlot.getX()+5)){
      if(between(pillageSlot.getY(), clickY, pillageSlot.getX()+4)){
        return pillageSlot;
      }
    }

    if(between(spoilsSlot.getX(), clickX, spoilsSlot.getX()+5)){
      if(between(spoilsSlot.getY(), clickY, spoilsSlot.getX()+4)){
        return spoilsSlot;
      }
    }

    for(int i=0; i<3; i++){
      if(between(activeSlots[i].getX(), clickX, activeSlots[i].getX()+5)){ 
        if(between(activeSlots[i].getY(), clickY, activeSlots[i].getX()+4)){
          return activeSlots[i];
        }
      }
    }
*/

  
  return emptySlot;
}

bool Client::between(int a, int b, int c){
  if((a < b) && (b < c)){
    return true;
  }
  return false;
}

void Client::setClickedCardToMove(Slot clickedSlot, Table* table){
//If you later wish to add players then each needs its own for loop because of the naming of the slot arrays
  //check each slot of this player one's hand.
  for(int i = 1; i < table->players.at(0).getHand()->size()+1; i++){
    //if you click card hand in hand  
    if(( clickedSlot.getX() == p1CardSlots[i].getX()) && (clickedSlot.getY() == p1CardSlots[i].getY()) ){
      table->players.at(0).setMoveCard(clickedSlot.getCard());//then set move that card 
      //clickedSlot.setCard(emptyHandCard);
    }
  }
}

void Client::updateClient(Table* table){

  updateSlotValues(table);
  drawTable(table); 
  gameDisplay.updateScreen();
  // calls the game display to capture some input
  key = gameDisplay.captureInput();
  Slot clickedSlot = checkHitBoxes();
  
 
      // if a mouse event occurred
      if (key == -1) {
        // make a banner message
	#if VERBOSE
          messageString.str("");
          messageString << "A mouse event occurred x=" \
            << gameDisplay.getMouseEventX() << ", y=" \
            << gameDisplay.getMouseEventY() << ", bstate=" \
            << gameDisplay.getMouseEventButton();
          // display a banner message
          gameDisplay.bannerTop(messageString.str());
	#endif
        // record the location of the mouse event
        clickX = gameDisplay.getMouseEventX();
        clickY = gameDisplay.getMouseEventY();
	//record which slot was clicked
	Slot clickedSlot = checkHitBoxes();
        // check if it was a left click
        if (gameDisplay.getMouseEventButton()&LEFT_CLICK) {
	  setClickedCardToMove(clickedSlot, table);//this sets a player's move based on which slot was clicked


	//ACTIVE TESTING: Print out the rank at bot right:
	#if VERBOSE
	  Card* temp2Card = new Card(hearts, joker, 99);
	  temp2Card = clickedSlot.getCard();
	  Card thisCard = *temp2Card;
	  // delete tempCard;
	  int num = thisCard.getRank();
	  

	  //cout<<num<<endl;
	  string result;
	  ostringstream convert;
	  convert <<num;
	  result = "Your Card's Rank is: " + convert.str();
          gameDisplay.bannerBottom(result);
	#endif
	}
    }  
}


